{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "3xW4O0zuKfWD"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "from openai import OpenAI\n",
        "import rich\n",
        "import requests\n",
        "import json\n",
        "from google.colab import userdata"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "api_key = userdata.get('OPENAI_API_KEY')\n",
        "MODEL = \"gpt-4o-mini\"\n",
        "\n",
        "openai = OpenAI(api_key=api_key)"
      ],
      "metadata": {
        "id": "vUydnLeLKs03"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Calling a function and sending the result back to Chat API and Responses API**"
      ],
      "metadata": {
        "id": "blCx6gu1Vl46"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Defining function that fetch current weather from API"
      ],
      "metadata": {
        "id": "nznKPApuXC9z"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def get_weather(latitude, longitude):\n",
        "    response = requests.get(f\"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m,wind_speed_10m&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m\")\n",
        "    data = response.json()\n",
        "    print(f\"get_weather function called to get weather for latitude = {latitude}, longitude = {longitude}\")\n",
        "    print(f\"And result is  = {data['current']['temperature_2m']}\")\n",
        "    return data['current']['temperature_2m']"
      ],
      "metadata": {
        "id": "qvJhp-k5XEmW"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Chat Completion API\n",
        "\n",
        "https://platform.openai.com/docs/guides/function-calling?api-mode=chat"
      ],
      "metadata": {
        "id": "5wlqKfVBKyjD"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Defining the structure schema of the function to be passed as a tool in the API."
      ],
      "metadata": {
        "id": "EgXT84U9Tfqr"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def get_weather_function_chat():\n",
        "    return {\n",
        "        \"type\": \"function\",\n",
        "        \"function\": { # This property is removed from responses API\n",
        "            \"name\": \"get_weather\",\n",
        "            \"description\": \"Get the weather for a location. Call this whenever you need to know the weather, for example when a customer asks 'What's the weather like in this city'\",\n",
        "            \"parameters\": {\n",
        "                \"type\": \"object\",\n",
        "                \"properties\": {\n",
        "                    \"latitude\": {\n",
        "                        \"type\": \"number\",\n",
        "                        \"description\": \"Latitude of the location\"\n",
        "                    },\n",
        "                    \"longitude\": {\n",
        "                        \"type\": \"number\",\n",
        "                        \"description\": \"Longitude of the location\"\n",
        "                    }\n",
        "                },\n",
        "                \"required\": [\"latitude\", \"longitude\"],\n",
        "                \"additionalProperties\": False\n",
        "            },\n",
        "            \"strict\": True\n",
        "        }\n",
        "    }"
      ],
      "metadata": {
        "id": "dBrUkMCUKz0s"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "First Step where model will responed with tool call request"
      ],
      "metadata": {
        "id": "xvVxw5mGXWJ6"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "messages=[\n",
        "    {\"role\": \"developer\", \"content\": \"You are a helpful assistant and provide update on weather in a city.\"},\n",
        "    {\"role\": \"user\", \"content\": \"What's the weather like in Karachi, Pakistan?\"}\n",
        "    # {\"role\": \"user\", \"content\": \"NYC\"}\n",
        "]\n",
        "tools = [get_weather_function_chat()]\n",
        "response = openai.chat.completions.create(\n",
        "    model=MODEL,\n",
        "    messages=messages,\n",
        "    tools = tools\n",
        ")\n",
        "\n",
        "rich.print(response.choices[0])\n",
        "print(\"Finish Reason = \", response.choices[0].finish_reason)\n",
        "rich.print(response.choices[0].message.tool_calls)\n"
      ],
      "metadata": {
        "id": "WItchxDLK2x6",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 466
        },
        "outputId": "0aea165b-dd3c-4556-b86c-d811185f0db3"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "\u001b[1;35mChoice\u001b[0m\u001b[1m(\u001b[0m\n",
              "    \u001b[33mfinish_reason\u001b[0m=\u001b[32m'tool_calls'\u001b[0m,\n",
              "    \u001b[33mindex\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
              "    \u001b[33mlogprobs\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
              "    \u001b[33mmessage\u001b[0m=\u001b[1;35mChatCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n",
              "        \u001b[33mcontent\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
              "        \u001b[33mrefusal\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
              "        \u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n",
              "        \u001b[33mannotations\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n",
              "        \u001b[33maudio\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
              "        \u001b[33mfunction_call\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
              "        \u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\n",
              "            \u001b[1;35mChatCompletionMessageToolCall\u001b[0m\u001b[1m(\u001b[0m\n",
              "                \u001b[33mid\u001b[0m=\u001b[32m'call_QN4XxX4Wyrxt98BrU2v8vN3q'\u001b[0m,\n",
              "                \u001b[33mfunction\u001b[0m=\u001b[1;35mFunction\u001b[0m\u001b[1m(\u001b[0m\u001b[33marguments\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"latitude\":24.8607,\"longitude\":67.0011\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'get_weather'\u001b[0m\u001b[1m)\u001b[0m,\n",
              "                \u001b[33mtype\u001b[0m=\u001b[32m'function'\u001b[0m\n",
              "            \u001b[1m)\u001b[0m\n",
              "        \u001b[1m]\u001b[0m\n",
              "    \u001b[1m)\u001b[0m\n",
              "\u001b[1m)\u001b[0m\n"
            ],
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Choice</span><span style=\"font-weight: bold\">(</span>\n",
              "    <span style=\"color: #808000; text-decoration-color: #808000\">finish_reason</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'tool_calls'</span>,\n",
              "    <span style=\"color: #808000; text-decoration-color: #808000\">index</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
              "    <span style=\"color: #808000; text-decoration-color: #808000\">logprobs</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
              "    <span style=\"color: #808000; text-decoration-color: #808000\">message</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ChatCompletionMessage</span><span style=\"font-weight: bold\">(</span>\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">content</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">refusal</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">role</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'assistant'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">annotations</span>=<span style=\"font-weight: bold\">[]</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">audio</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">function_call</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">tool_calls</span>=<span style=\"font-weight: bold\">[</span>\n",
              "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ChatCompletionMessageToolCall</span><span style=\"font-weight: bold\">(</span>\n",
              "                <span style=\"color: #808000; text-decoration-color: #808000\">id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'call_QN4XxX4Wyrxt98BrU2v8vN3q'</span>,\n",
              "                <span style=\"color: #808000; text-decoration-color: #808000\">function</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Function</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">arguments</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'{\"latitude\":24.8607,\"longitude\":67.0011}'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">name</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'get_weather'</span><span style=\"font-weight: bold\">)</span>,\n",
              "                <span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'function'</span>\n",
              "            <span style=\"font-weight: bold\">)</span>\n",
              "        <span style=\"font-weight: bold\">]</span>\n",
              "    <span style=\"font-weight: bold\">)</span>\n",
              "<span style=\"font-weight: bold\">)</span>\n",
              "</pre>\n"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Finish Reason =  tool_calls\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "\u001b[1m[\u001b[0m\n",
              "    \u001b[1;35mChatCompletionMessageToolCall\u001b[0m\u001b[1m(\u001b[0m\n",
              "        \u001b[33mid\u001b[0m=\u001b[32m'call_QN4XxX4Wyrxt98BrU2v8vN3q'\u001b[0m,\n",
              "        \u001b[33mfunction\u001b[0m=\u001b[1;35mFunction\u001b[0m\u001b[1m(\u001b[0m\u001b[33marguments\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"latitude\":24.8607,\"longitude\":67.0011\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'get_weather'\u001b[0m\u001b[1m)\u001b[0m,\n",
              "        \u001b[33mtype\u001b[0m=\u001b[32m'function'\u001b[0m\n",
              "    \u001b[1m)\u001b[0m\n",
              "\u001b[1m]\u001b[0m\n"
            ],
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>\n",
              "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ChatCompletionMessageToolCall</span><span style=\"font-weight: bold\">(</span>\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'call_QN4XxX4Wyrxt98BrU2v8vN3q'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">function</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Function</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">arguments</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'{\"latitude\":24.8607,\"longitude\":67.0011}'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">name</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'get_weather'</span><span style=\"font-weight: bold\">)</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'function'</span>\n",
              "    <span style=\"font-weight: bold\">)</span>\n",
              "<span style=\"font-weight: bold\">]</span>\n",
              "</pre>\n"
            ]
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Second Step where we are calling the `get_weather` function and sending the response back to Chat API"
      ],
      "metadata": {
        "id": "B7ZJl9AEXdV4"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "To send the result of function call we need to send specific format object into Chat API call\n",
        "\n",
        "```\n",
        "new_message = {\n",
        "    \"role\": \"tool\",\n",
        "    \"content\": <output of function call>,\n",
        "    \"tool_call_id\": tool_call.id\n",
        "}\n",
        "```"
      ],
      "metadata": {
        "id": "OCdftylSXgrc"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "if response.choices[0].finish_reason == \"tool_calls\": # Check if finish_reason is tool_calls\n",
        "    tool_call = response.choices[0].message.tool_calls[0]\n",
        "    arguments = json.loads(tool_call.function.arguments)\n",
        "    latitude = arguments.get(\"latitude\")\n",
        "    longitude = arguments.get(\"longitude\")\n",
        "    # weather = get_weather(latitude, longitude) # Both will work\n",
        "    weather = get_weather(**arguments)\n",
        "    new_message = { # Properties of this object will be different in responses API\n",
        "        \"role\": \"tool\",\n",
        "        \"content\": json.dumps({\"latitude\": latitude, \"longitude\": longitude, \"weather\": weather}),\n",
        "        \"tool_call_id\": tool_call.id\n",
        "    }\n",
        "    # Important: we will append the previous message (response.choices[0].message)\n",
        "    messages.append(response.choices[0].message)\n",
        "    messages.append(new_message)\n",
        "    # Calling the Chat API again with all the history messages and the new message\n",
        "    response2 = openai.chat.completions.create(model=MODEL, messages=messages, tools=tools)\n",
        "    print(\"Model Response2 = \",response2.choices[0].message.content)\n",
        "    # Notice the finish_reason of the response, it value is \"stop\"\n",
        "    print(\"Finish Reason = \",response2.choices[0].finish_reason)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "dbCwGXwGXlf7",
        "outputId": "9fadbf86-0161-4deb-ba84-3bf0bc10029f"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "get_weather function called to get weather for latitude = 24.8607, longitude = 67.0011\n",
            "And result is  = 25.5\n",
            "Model Response2 =  The current weather in Karachi, Pakistan is 25.5°C. If you need more specific details, feel free to ask!\n",
            "Finish Reason =  stop\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Responses API\n",
        "\n",
        "https://platform.openai.com/docs/guides/function-calling?api-mode=responses"
      ],
      "metadata": {
        "id": "tCzSosP5K-JR"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Note: Check the difference between json objects for function"
      ],
      "metadata": {
        "id": "Q4E9IoxrTzFV"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def get_weather_function_response():\n",
        "    return {\n",
        "        \"type\": \"function\",  # There is no function property in the response API\n",
        "        \"name\": \"get_weather\",\n",
        "        \"description\": \"Get the weather for a location. Call this whenever you need to know the weather, for example when a customer asks 'What's the weather like in this city'\",\n",
        "        \"parameters\": {\n",
        "            \"type\": \"object\",\n",
        "            \"properties\": {\n",
        "                \"latitude\": {\n",
        "                    \"type\": \"number\",\n",
        "                    \"description\": \"Latitude of the location\"\n",
        "                },\n",
        "                \"longitude\": {\n",
        "                    \"type\": \"number\",\n",
        "                    \"description\": \"Longitude of the location\"\n",
        "                }\n",
        "            },\n",
        "            \"required\": [\"latitude\", \"longitude\"],\n",
        "            \"additionalProperties\": False\n",
        "        },\n",
        "        \"strict\": True\n",
        "    }"
      ],
      "metadata": {
        "id": "2IPLSF30K--S"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Using old way of sending history messages in every call"
      ],
      "metadata": {
        "id": "KTg9iYRcX5WQ"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "First Step where model will responed with tool call request"
      ],
      "metadata": {
        "id": "l4nhpXieX7w6"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "messages=[\n",
        "    {\"role\": \"developer\", \"content\": \"You are a helpful assistant and provide update on weather in a city.\"},\n",
        "    # {\"role\": \"user\", \"content\": \"What's the weather like in Karachi, Pakistan?\"}\n",
        "    # {\"role\": \"user\", \"content\": \"NYC\"}\n",
        "     {\"role\": \"user\", \"content\": \"Berlin\"}\n",
        "]\n",
        "tools = [get_weather_function_response()]\n",
        "\n",
        "response = openai.responses.create(\n",
        "    model=MODEL,\n",
        "    input=messages,\n",
        "    tools = tools\n",
        ")\n",
        "\n",
        "print(\"Status = \",response.status) # Status will not indicate the tool call\n",
        "print(response.output_text) # Empty\n",
        "rich.print(response.output)\n",
        "# rich.print(response)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 212
        },
        "id": "fFzGxrJWWiYC",
        "outputId": "a7147f2b-cdbc-474d-91b2-a5a0e617791d"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Status =  completed\n",
            "\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "\u001b[1m[\u001b[0m\n",
              "    \u001b[1;35mResponseFunctionToolCall\u001b[0m\u001b[1m(\u001b[0m\n",
              "        \u001b[33marguments\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"latitude\":52.52,\"longitude\":13.405\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n",
              "        \u001b[33mcall_id\u001b[0m=\u001b[32m'call_CqCPpXMNpx9dPr9F4SrgPunj'\u001b[0m,\n",
              "        \u001b[33mname\u001b[0m=\u001b[32m'get_weather'\u001b[0m,\n",
              "        \u001b[33mtype\u001b[0m=\u001b[32m'function_call'\u001b[0m,\n",
              "        \u001b[33mid\u001b[0m=\u001b[32m'fc_67e2e975e9cc8192b7bfc5d9afd83cfc03f8040ad152ec7e'\u001b[0m,\n",
              "        \u001b[33mstatus\u001b[0m=\u001b[32m'completed'\u001b[0m\n",
              "    \u001b[1m)\u001b[0m\n",
              "\u001b[1m]\u001b[0m\n"
            ],
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>\n",
              "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ResponseFunctionToolCall</span><span style=\"font-weight: bold\">(</span>\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">arguments</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'{\"latitude\":52.52,\"longitude\":13.405}'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">call_id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'call_CqCPpXMNpx9dPr9F4SrgPunj'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">name</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'get_weather'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'function_call'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'fc_67e2e975e9cc8192b7bfc5d9afd83cfc03f8040ad152ec7e'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">status</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'completed'</span>\n",
              "    <span style=\"font-weight: bold\">)</span>\n",
              "<span style=\"font-weight: bold\">]</span>\n",
              "</pre>\n"
            ]
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Second Step where we are calling the `get_weather` function and sending the response back to Responses API"
      ],
      "metadata": {
        "id": "R0QHg7tSYSEg"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "To send the result of function call we need to send specific format object into Responses API call\n",
        "\n",
        "Note: object has different property names.\n",
        "\n",
        "```\n",
        "{\n",
        "    \"type\": \"function_call_output\",\n",
        "    \"call_id\": tool_call.call_id,\n",
        "    \"output\": <output of function call>,\n",
        "}\n",
        "```"
      ],
      "metadata": {
        "id": "TqY02G35YU8y"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "if response.output[0].type == \"function_call\": # Check if output type is function_call\n",
        "    tool_call = response.output[0]\n",
        "    arguments = json.loads(tool_call.arguments)\n",
        "    latitude = arguments.get(\"latitude\")\n",
        "    longitude = arguments.get(\"longitude\")\n",
        "    # weather = get_weather(latitude, longitude) # Both will work\n",
        "    weather = get_weather(**arguments)\n",
        "    new_message = {\n",
        "        \"type\": \"function_call_output\",\n",
        "        \"call_id\": tool_call.call_id,\n",
        "        # \"output\": str(weather)\n",
        "        # Because of json object in output Responses API sometimes does not generate expected output\n",
        "        \"output\":  json.dumps({\"latitude\": latitude, \"longitude\": longitude, \"weather\": weather}),\n",
        "    }\n",
        "    # Important: we will append the tool call (response.output[0])\n",
        "    messages.append(response.output[0])\n",
        "    messages.append(new_message)\n",
        "    # Calling the Responses API again with all the history messages and the new message\n",
        "    response2 = openai.responses.create(model=MODEL, input=messages,tools = tools)\n",
        "    print(\"Model Response2 = \",response2.output_text)\n",
        "    print(\"Status = \",response2.status)\n",
        "    # rich.print(response2)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "TROvT0hKX-yA",
        "outputId": "0915a56d-366a-4344-fbf6-215e0bb3aae8"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "get_weather function called to get weather for latitude = 52.52, longitude = 13.405\n",
            "And result is  = 8.0\n",
            "Model Response2 =  The weather in Berlin is currently quite cool, with a temperature of around 8°C. If you need more specific details like conditions or forecasts, let me know!\n",
            "Status =  completed\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Using new way of conversation state by sending perivous reponse id"
      ],
      "metadata": {
        "id": "NrxQlRWjYaNt"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "First Step where model will responed with tool call request"
      ],
      "metadata": {
        "id": "5wgUU53HYd43"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# This section is same as above\n",
        "\n",
        "messages=[\n",
        "    {\"role\": \"developer\", \"content\": \"You are a helpful assistant and provide update on weather in a city.\"},\n",
        "    # {\"role\": \"user\", \"content\": \"What's the weather like in Karachi, Pakistan?\"}\n",
        "    # {\"role\": \"user\", \"content\": \"NYC\"}\n",
        "     {\"role\": \"user\", \"content\": \"Berline\"}\n",
        "]\n",
        "tools = [get_weather_function_response()]\n",
        "\n",
        "response = openai.responses.create(\n",
        "    model=MODEL,\n",
        "    input=messages,\n",
        "    tools = tools\n",
        ")\n",
        "\n",
        "print(\"Status = \",response.status) # Status will not indicate the tool call\n",
        "print(response.output_text) # Empty\n",
        "rich.print(response.output)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 212
        },
        "id": "YJh9yNK5YedH",
        "outputId": "3a0e79b0-dd11-4a72-d12d-3699d59c2359"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Status =  completed\n",
            "\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "\u001b[1m[\u001b[0m\n",
              "    \u001b[1;35mResponseFunctionToolCall\u001b[0m\u001b[1m(\u001b[0m\n",
              "        \u001b[33marguments\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"latitude\":52.520008,\"longitude\":13.404954\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n",
              "        \u001b[33mcall_id\u001b[0m=\u001b[32m'call_dwHoh7PoVzXP8i2FTUBbQR4o'\u001b[0m,\n",
              "        \u001b[33mname\u001b[0m=\u001b[32m'get_weather'\u001b[0m,\n",
              "        \u001b[33mtype\u001b[0m=\u001b[32m'function_call'\u001b[0m,\n",
              "        \u001b[33mid\u001b[0m=\u001b[32m'fc_67e2ea01b6e88192b92725629f0034e30f0dfe54a3d226a1'\u001b[0m,\n",
              "        \u001b[33mstatus\u001b[0m=\u001b[32m'completed'\u001b[0m\n",
              "    \u001b[1m)\u001b[0m\n",
              "\u001b[1m]\u001b[0m\n"
            ],
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>\n",
              "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">ResponseFunctionToolCall</span><span style=\"font-weight: bold\">(</span>\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">arguments</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'{\"latitude\":52.520008,\"longitude\":13.404954}'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">call_id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'call_dwHoh7PoVzXP8i2FTUBbQR4o'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">name</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'get_weather'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'function_call'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'fc_67e2ea01b6e88192b92725629f0034e30f0dfe54a3d226a1'</span>,\n",
              "        <span style=\"color: #808000; text-decoration-color: #808000\">status</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'completed'</span>\n",
              "    <span style=\"font-weight: bold\">)</span>\n",
              "<span style=\"font-weight: bold\">]</span>\n",
              "</pre>\n"
            ]
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Second Step where we are calling the `get_weather` function and sending the response back to Responses API"
      ],
      "metadata": {
        "id": "h23yvgMSYk15"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "The only difference in below section is how messages are sent."
      ],
      "metadata": {
        "id": "S3N_6IHXYruu"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "if response.output[0].type == \"function_call\": # Check if output type is function_call\n",
        "    tool_call = response.output[0]\n",
        "    arguments = json.loads(tool_call.arguments)\n",
        "    latitude = arguments.get(\"latitude\")\n",
        "    longitude = arguments.get(\"longitude\")\n",
        "    # weather = get_weather(latitude, longitude) # Both will work\n",
        "    weather = get_weather(**arguments)\n",
        "    new_message = {\n",
        "        \"type\": \"function_call_output\",\n",
        "        \"call_id\": tool_call.call_id,\n",
        "        # \"output\": str(weather)\n",
        "        # Because of json object in output Responses API sometimes does not generate expected output\n",
        "        \"output\":  json.dumps({\"latitude\": latitude, \"longitude\": longitude, \"weather\": weather}),\n",
        "    }\n",
        "    # Not needed now, because we are sending the previous response id\n",
        "    # messages.append(response.output[0])\n",
        "\n",
        "    # Emptying the messages array because we are sending the previous response id,\n",
        "    # therefore we don't need to send the previous message\n",
        "    messages = []\n",
        "    messages.append(new_message)\n",
        "    # Note the previous_response_id\n",
        "    response2 = openai.responses.create(model=MODEL, input=messages,tools = tools, previous_response_id=response.id)\n",
        "    print(\"Model Response2 = \",response2.output_text)\n",
        "    print(\"Status = \",response2.status)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cfWaPu4JYleE",
        "outputId": "5e07347e-2442-4eb8-da2b-99e09d6e51c3"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "get_weather function called to get weather for latitude = 52.520008, longitude = 13.404954\n",
            "And result is  = 8.0\n",
            "Model Response2 =  The current weather in Berlin is around 8°C. If you need more details or specific weather conditions, feel free to ask!\n",
            "Status =  completed\n"
          ]
        }
      ]
    }
  ]
}